﻿using Mapster;
using XYS.Core.Models;
using XYS.Core.Util;
using XYS.Service.Core.Models.APILoggerModels;

namespace XYS.Core.Service.APILoggerService.LoggerWriters
{
    /// <summary>
    /// 
    /// </summary>
    public class FileChannel : IAPILogChannel
    {
        private static readonly string LogPath = $"logs/apis/";

        /// <summary>
        /// 是否启用
        /// </summary>
        public bool Enable => true;

        /// <summary>
        /// 日志进入通道
        /// </summary>
        /// <param name="request"></param>
        /// <exception cref="NotImplementedException"></exception>
        public ResultModel EnterCannel<T>(IEnumerable<T> request)
            where T : class, IApiPathField, IResponseBodyField
        {
            try
            {
                var requestMap = request.GroupBy(e => e.ApiPath)
                    .ToDictionary(e => e.Key, e => e.ToList());

                foreach (var key in requestMap.Keys)
                {
                    var list = requestMap[key];
                    var pathArray = key.Split("/").ToList();

                    string apiPath = string.Join("/", pathArray.Take(3));
                    string fileName = string.Join("-", pathArray.Skip(3));

                    string dirPath = $"{LogPath}{DateTime.Now:yyyy-MM-dd}{apiPath}/";
                    if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
                    string path = $"{dirPath}/{fileName}.log";
                    if (!File.Exists(path))
                    {
                        var fs = File.Create(path);
                        fs.Close();
                    }

                    foreach (var item in list)
                    {
                        string text = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]{item.ToJson()}\r\n";
                        File.AppendAllText(path, text);

                        var result = item.ResponseBody.Adapt<ResultModel<dynamic>>();
                        if (result != null)
                        {
                            string dirPathDetail = $"{dirPath}{((result.Succeeded || result.StatusCode == (int)EnumStatusCode.OK) ? "Succeeded" : "Failed")}/";
                            if (!Directory.Exists(dirPathDetail)) Directory.CreateDirectory(dirPathDetail);
                            string pathDetail = $"{dirPathDetail}{fileName}.log";
                            if (!File.Exists(pathDetail))
                            {
                                var fs = File.Create(pathDetail);
                                fs.Close();
                            }
                            File.AppendAllText(pathDetail, text);
                        }
                    }
                }
                return ResultModel.Success;
            }
            catch (Exception ex) { return ResultModel.Failed(ex); }
        }

        /// <summary>
        /// 日志 进入通道
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task EnterCannel<T>(T request) where T : class, IApiPathField, IResponseBodyField
        {
            string text = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]{request.ToJson()}\r\n";

            var pathArray = request.ApiPath.Split("/").ToList();

            string apiPath = string.Join("/", pathArray.Take(3));
            string fileName = string.Join("-", pathArray.Skip(3));

            string dirPath = $"{LogPath}{DateTime.Now:yyyy-MM-dd}{apiPath}/";
            if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
            string path = $"{dirPath}/{fileName}.log";
            if (!File.Exists(path))
            {
                var fs = File.Create(path);
                fs.Close();
            }
            await File.AppendAllTextAsync(path, text);

            var result = request.ResponseBody.Adapt<ResultModel<dynamic>>();
            if (result != null)
            {
                string dirPathDetail = $"{dirPath}{((result.Succeeded || result.StatusCode == (int)EnumStatusCode.OK) ? "Succeeded" : "Failed")}/";
                if (!Directory.Exists(dirPathDetail)) Directory.CreateDirectory(dirPathDetail);
                string pathDetail = $"{dirPathDetail}{fileName}.log";
                if (!File.Exists(pathDetail))
                {
                    var fs = File.Create(pathDetail);
                    fs.Close();
                }
                await File.AppendAllTextAsync(pathDetail, text);
            }

        }

    }
}
